// eee.Sheffield.PZ.Imaging
//
// Copyright ?Ping Zou, 2006
// sg71.cherub@gmail.com

using System;
using System.Collections.Generic;
using System.Text;
using eee.Sheffield.PZ.Math;
using System.Drawing;
using System.Drawing.Imaging;

namespace eee.Sheffield.PZ.Imaging.ImageFilter
{
    public class EdgeMap : ImageFilter, IGraylevelImageFilter
    {
        #region Fields
        /// <summary>
        /// standard deviation of the distribution
        /// </summary>
        private double _sigma;       
        //private string _flag = "[Image -> Gradient -> Edge Map]";
        #endregion

        #region Properties
        public double Sigma { get { return _sigma; } set { _sigma = value; } }
        //public string Log() { return _log; }
        //public string Flag() { return _flag; }
        #endregion

        #region constructor
        /// <summary>
        /// empty constructor
        /// </summary>
        public EdgeMap() : this(0) { }
        /// <summary>
        /// imput standard deviation of the distribution
        /// </summary>
        /// <param name="sigma"></param>
        public EdgeMap(double sigma)
        {
            _flag = "[Image -> Gradient -> Edge Map]";
            _sigma = sigma;
        }
        #endregion

        #region Apply filter
        //public Bitmap ApplyGraylevelImageFilter(Bitmap srcImage) { return Apply(srcImage, out _log); }
        //public PZMath_matrix ApplyDoubleGraylevelImageFilter(PZMath_matrix srcMatrix) { return ApplyDouble(srcMatrix, out _log); }

        //private Bitmap Apply(Bitmap srcImage, out string logText)
        //{
        //    PZMath_matrix srcMatrix = _converter.ConvertGraylevelBitmapToMatrix(srcImage);
        //    PZMath_matrix dstMatrix = ApplyDouble(srcMatrix, out logText);
        //    Bitmap dstImage = _converter.ConvertMatrixToGraylevelBitmap(dstMatrix, true);
        //    return dstImage;
        //}   
  
        protected override PZMath_matrix ApplyDoubleGraylevelImageFilter(PZMath_matrix srcMatrix, out string logText)
        {
            // 1. Gaussian Filter
            GaussianSmoothing gaussianSmoothing = new GaussianSmoothing(_sigma);
            PZMath_matrix afterGaussian = gaussianSmoothing.ApplyDoubleGraylevelImageFilter(srcMatrix);
            string gaussianSmoothLog = gaussianSmoothing.LogText;
            // 2. two gradient operator
            
            SobelX sobelX = new SobelX();
            SobelY sobelY = new SobelY();
            //GradientXCentralDifference sobelX = new GradientXCentralDifference();
            //GradientYCentralDifference sobelY = new GradientYCentralDifference();
            PZMath_matrix gradientX = sobelX.ApplyDoubleGraylevelImageFilter(afterGaussian);
            string sobelXLog = sobelX.LogText;            
            PZMath_matrix gradientY = sobelY.ApplyDoubleGraylevelImageFilter(afterGaussian);
            string sobelYLog = sobelY.LogText;
            //gradientX.WriteFile("gradientX.txt");
            //gradientY.WriteFile("gradientY.txt");

            #region source and dst matrix
            // get source
            int width = srcMatrix.ColumnCount;
            int height = srcMatrix.RowCount;

            // create dstMatrix
            PZMath_matrix dstMatrix = new PZMath_matrix(height, width);
            #endregion

            // for each pixel
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    dstMatrix[y, x] = System.Math.Sqrt(gradientX[y, x] * gradientX[y, x] + gradientY[y, x] * gradientY[y, x]);
                    //dstMatrix[y, x] = gradientX[y, x] * gradientX[y, x] + gradientY[y, x] * gradientY[y, x];
                }
            }

            // normalize to [0, 1];
            dstMatrix.Normalize();
            logText = "succeeds.";
            return dstMatrix;
        } // ApplyDoubleGraylevelImageFilter()

        protected override PZMath_matrix[] ApplyDoubleColourImageFilter(PZMath_matrix[] srcMatrixArray, out string logText)
        {
            // TODO: add this function

            throw new Exception("The method or operation is not implemented.");
        } // ApplyDoubleColourImageFilter()
        #endregion
    }
}
